package com.ysx66.verification.base.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ysx66.verification.base.domain.ImageVerify;
import com.ysx66.verification.base.service.VerifyService;

@Controller
public class VerifiyCtrl {
	
	@Autowired
	private StringRedisTemplate redisTemplate;
	@Resource
	private VerifyService verifyService;
	public void setRedisTemplate(StringRedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}
	public void setVerifyService(VerifyService verifyService) {this.verifyService = verifyService;}

	

	@GetMapping("")
	public String init(){
		return "/drawDemo";
	}
	
	@RequestMapping("i")
	@ResponseBody
	public String generateCode() throws Exception{
		long size = redisTemplate.execute(new RedisCallback<Long>() {
			@Override
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.dbSize();
			}
		});
		if(size <= 10){
			this.verifyService.generate(10);
		}
		String key = redisTemplate.randomKey();
		if(StringUtils.isNotEmpty(key)){
			boolean result = redisTemplate.hasKey(key);
			if(result){
				return redisTemplate.opsForValue().get(key);
			}
		}
		return JsonUtil.obj2json(new ImageVerify());
	}
	


	@RequestMapping("generate")
	@ResponseBody
	public String generate(HttpServletRequest request) throws Exception{
		verifyService.generate();
		return "success";
	}
	
	@RequestMapping("load")
	public void load(@RequestParam("code")String code
			,HttpServletResponse response) throws FileNotFoundException, IOException{
		code = URLDecoder.decode(code, "utf-8");
		InputStream in = IOUtils.toBufferedInputStream(new FileInputStream(new File(code)));
		ServletOutputStream out = response.getOutputStream();
		byte[] buf = new byte[1024 * 8];
		int length = 0;
		while((length = in.read(buf)) != -1){
			out.write(buf, 0, length);
		}
		out.flush();
		out.close();
	}
	
	@PostMapping("")
	@ResponseBody
	public String verify(@RequestParam("code")String code
			,@RequestParam("value")int value) throws Exception{
		boolean result = redisTemplate.hasKey(code);
		if(result){
			ImageVerify verify = JsonUtil.json2pojo(redisTemplate.opsForValue().get(code),ImageVerify.class);
			redisTemplate.delete(code);
			int offset = verify.getX() - value;
			if(offset <= 2 && offset >= -2){
				return "success";
			}
		}
		return "error";
	}
	
	private static class JsonUtil{
		private final static ObjectMapper objectMapper = new ObjectMapper();  
		
		public static <T> T json2pojo(String jsonStr, Class<T> clazz)  throws Exception {  
			return objectMapper.readValue(jsonStr, clazz);  
		}
		
		public static String obj2json(Object obj) throws Exception {  
	        return objectMapper.writeValueAsString(obj);  
	    } 
	}
	
}
